/* 
 * File:   Trayectoria.cpp
 * Author: 75.02 - Grupo 7, 2do cuatrimestre 2012.
 * 
 * Created on 31 de octubre de 2012, 18:48
 */

#include "Trayectoria.h"

using namespace TP::Matematica;
using namespace TP::Juego::Motorizacion::Fisica;

Trayectoria::Trayectoria() {}

Trayectoria::Trayectoria(Posicion* pPosicion, Vector2D* pVelocidad, Vector2D* pAceleracion) {
    
    // Incialmente, la posicion actual es la posicion inicial.
    this->_posicionInicial = pPosicion;
    this->_posicionActual = pPosicion;
    
    this->_velocidadInicial = pVelocidad;
    this->_velocidadActual = pVelocidad;
    
    this->_aceleracion = pAceleracion;
    
}

Trayectoria::~Trayectoria() {
}

Posicion* Trayectoria::getPosicionInicial(){
    return this->_posicionInicial;
}

Posicion* Trayectoria::getPosicion(){
    return this->_posicionActual;
}

Ticks Trayectoria::desplazar(Ticks pTiempo){

    // Computo la posición siguiente y la configuro como actual.
    Posicion* posicionPost = new Posicion();
    posicionPost->X(this->_posicionActual->X() + pTiempo * this->_velocidadActual->X() + 0.5 * this->_aceleracion->X()*pow(pTiempo, 2));
    posicionPost->Y(this->_posicionActual->Y() + pTiempo * this->_velocidadActual->Y() + 0.5 * this->_aceleracion->Y()*pow(pTiempo, 2));
    delete this->_posicionActual;
    this->_posicionActual = posicionPost;

    // Actualizo la velocidad.
    Vector2D* velocidadPost = new Vector2D();
    velocidadPost->X(this->_velocidadActual->X()+this->_aceleracion->X()*pTiempo);
    velocidadPost->Y(this->_velocidadActual->Y()+this->_aceleracion->Y()*pTiempo);
    delete this->_velocidadActual;
    this->_velocidadActual = velocidadPost;
    
    return pTiempo;
}

string Trayectoria::aXML(){

    TiXmlDocument* doc = new TiXmlDocument();
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
    doc->LinkEndChild( decl );
    
    doc->LinkEndChild(this->aElementoXML());

    TiXmlPrinter printer;
    doc->Accept(&printer);
    return printer.CStr();    
}

string Trayectoria::aXML(const string& pPath){

    TiXmlDocument* doc = new TiXmlDocument(pPath.c_str());
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
    doc->LinkEndChild( decl );
    
    doc->LinkEndChild(this->aElementoXML());
    
    TiXmlPrinter printer;
    doc->Accept(&printer);
    return printer.CStr();    
}

void Trayectoria::parseXML (const string& pDescriptor){

    TiXmlDocument doc;
    doc.Parse(pDescriptor.c_str(), 0, TIXML_ENCODING_UTF8);
    this->deElementoXML(doc.FirstChildElement());
}

TiXmlElement* Trayectoria::aElementoXML (){
    
    TiXmlElement * element = new TiXmlElement("Trayectoria");
    
    element->LinkEndChild(this->_posicionInicial->aElementoXML());
    element->LinkEndChild(this->_posicionActual->aElementoXML());
    element->LinkEndChild(this->_velocidadInicial->aElementoXML());
    element->LinkEndChild(this->_velocidadActual->aElementoXML());
    element->LinkEndChild(this->_aceleracion->aElementoXML());

    return element;
}

void Trayectoria::deElementoXML (TiXmlElement* pElemento){

    if (strcmp (pElemento->Value(), "Trayectoria") == 0)
    {
        this->_posicionInicial = new Posicion();
        this->_posicionActual = new Posicion();
        this->_velocidadInicial = new Vector2D();
        this->_velocidadActual = new Vector2D();
        this->_aceleracion= new Vector2D();
        
        this->_posicionInicial->deElementoXML(pElemento->FirstChildElement());
        this->_posicionActual->deElementoXML(pElemento->FirstChildElement()->NextSiblingElement());
        this->_velocidadInicial->deElementoXML(pElemento->FirstChildElement()->NextSiblingElement()->NextSiblingElement());
        this->_velocidadActual->deElementoXML(pElemento->FirstChildElement()->NextSiblingElement()->NextSiblingElement()->NextSiblingElement());
        this->_aceleracion->deElementoXML(pElemento->FirstChildElement()->NextSiblingElement()->NextSiblingElement()->NextSiblingElement()->NextSiblingElement());
      
    }
}